package com.nowcoder.community.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * @author szq
 * @create 2023-01-25 16:47
 * @description Spring AOP测试
 */
//@Component
//@Aspect
public class AlphaAspect {
    // 1. 准备切点
    /*
    切入点表达式语法格式：
        execution([访问控制权限修饰符] 返回值类型 [全限定类名]方法名(形式参数列表) [异常])
        1.返回值类型:必填项,*表示返回值类型任意
        2.全限定类名:可选项,..代表当前包以及子包下的所有类,省略时表示所有的类
        3.方法名:必填项,*表示所有方法,set*表示所有的set方法
        4.形式参数列表:必填项
            a. () 表示没有参数的方法
            b. (..) 参数类型和个数随意的方法
            c. (*) 只有一个参数的方法
            d. (*, String) 第一个参数类型随意，第二个参数是String的。
     */
    @Pointcut("execution(* com.nowcoder.community.service.impl..*(..))")
    public void pointcut(){}

    // 前置通知
    @Before("pointcut()")
    public void before(){
        System.out.println("before");
    }

    // 后置通知
    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("afterReturning");
    }

    // 异常通知
    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("AfterThrowing");
    }

    // 最终通知
    @After("pointcut()")
    public void after(){
        System.out.println("After");
    }

    /**
     * 环绕通知
     * @param joinPoint 连接点
     * @return 目标方法返回值
     * @throws Throwable 异常
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("前环绕");
        Object obj = joinPoint.proceed();   // 调用目标方法
        System.out.println("后环绕");
        return obj;
    }
}
